#pragma once
#include "../../include/types.h"
#include "../../include/riscv.h"
#include "../proc/spinlock.h"
#include "fs.h"
#include "sleeplock.h"
#include "stat.h"
#include "../proc/proc.h"
#include "../file/string.h"
struct pipe;
  #define major(dev)  ((dev) >> 16 & 0xFFFF)
  #define minor(dev)  ((dev) & 0xFFFF)
  #define	mkdev(m,n)  ((uint)((m)<<16| (n)))
  #define NDIRECT 12
  
  // in-memory copy of an inode
  struct inode {
    uint32 dev;           // Device number
    uint32 inum;          // Inode number
    int ref;            // Reference count
    struct sleeplock lock; // protects everything below here
    int valid;          // inode has been read from disk?
  
    short type;         // copy of disk inode
    short major;
    short minor;
    short nlink;
    uint32 size;
    uint32 addrs[NDIRECT+1];
  };
  
  // map major device number to device functions.
  struct devsw {
    int (*read)(int, uint64, int);
    int (*write)(int, uint64, int);
  };
  
  extern struct devsw devsw[];
  
  struct file {
    enum { FD_NONE, FD_PIPE, FD_INODE, FD_DEVICE } type;
    int ref; // reference count
    char readable;
    char writable;
    struct pipe *pipe; // FD_PIPE
    struct inode *ip;  // FD_INODE and FD_DEVICE
    uint32 off;          // FD_INODE
    short major;       // FD_DEVICE
  };
  
struct filetable {
  spinlock lock;
  struct file file[NFILE];
};

extern struct filetable ftable;


  #define CONSOLE 1


  void
fileinit(void);
struct file* filealloc(void);
struct file* filedup(struct file *f);
void fileclose(struct file *f);
int filestat(struct file *f, uint64 addr);
int fileread(struct file *f, uint64 addr, int n);
int filewrite(struct file *f, uint64 addr, int n);